package com.qiu.aiteacherbacker.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiu.aiteacherbacker.common.ErrorCode;
import com.qiu.aiteacherbacker.common.ResultUtils;
import com.qiu.aiteacherbacker.config.fastgptConfig.AiKey;
import com.qiu.aiteacherbacker.config.fastgptConfig.KeyUtils;
import com.qiu.aiteacherbacker.exception.ExceptionUtils;
import com.qiu.aiteacherbacker.manager.ServiceRequests;


import com.qiu.aiteacherbacker.mapper.QuestionMapper;
import com.qiu.aiteacherbacker.model.domain.AiRequest.ChatMessage;
import com.qiu.aiteacherbacker.model.domain.AiRequest.Config;
import com.qiu.aiteacherbacker.model.domain.Question;
import com.qiu.aiteacherbacker.service.QuestionService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @author QIU
 * @description 针对表【question(题目)】的数据库操作Service实现
 * @createDate 2025-03-06 02:05:50
 */
@Service
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question>
        implements QuestionService {

    private final QuestionMapper questionMapper;

    public QuestionServiceImpl(QuestionMapper questionMapper) {
        this.questionMapper = questionMapper;
    }


    private static final ExecutorService executor = Executors.newFixedThreadPool(10);

    @Value("${question.splitter}")
    private String questionSplitter;

    @Value("${question.defaultTag}")
    private String defaultTag;

    @Autowired
    @Qualifier("taskExecutor")
    private Executor taskExecutor;


    /**
     * AI 生成题目
     *
     * @param stage           年级
     * @param count_direction 题目数量
     * @param direction       什么类型的题
     * @return boolean
     */
    @Transactional
    @Override
    public void getQuestion(String ChatId, String stage, int count_direction
            , String direction, String questions, int userId) {
        if (StringUtils.isAnyBlank(stage, direction, questions)) {
            ExceptionUtils.error(ErrorCode.PARAM_NOT_NULL);
        }

        Config config = new Config(
                KeyUtils.CtKey(AiKey.CtKey),
                KeyUtils.CtChatKey(AiKey.CtKey)
        );

        // 进行AI网络请求配置
        ServiceRequests serviceRequests = new ServiceRequests(config);

        String prompt = String.format("我的学习阶段是:%s,请生成%d道%s【%s】的题目,请一定要用 %s 来分割每一道题目",
                stage, count_direction, direction, questions, questionSplitter);

        List<ChatMessage> msg = Collections.singletonList(new ChatMessage(prompt));

        CompletableFuture.runAsync(() -> {
            System.out.println("异步开始");
            try {
                Map<String, Object> ret = serviceRequests.chatCompletions(ChatId, true, null, msg);
                String lastValue = parseResponse(ret);
                String[] split = lastValue.split(questionSplitter);

                if (split == null) {
                    ExceptionUtils.error(ErrorCode.Request_ERROR, "问题分割符 " + questionSplitter + " 出现问题");
                }

                List<Question> questionList = generateQuestions(split, stage, direction, userId);
//                boolean saveResult = this.saveBatch(questionList);
//
//                if (!saveResult) {
//                    ExceptionUtils.error(ErrorCode.SQL_ERROR, "[AI生成问题]插入数据失败");
//                }
                saveQuestionsAsync(questionList);
                System.out.println("异步结束");
            } catch (Exception e) {
                log.error("异步任务执行失败: " + e.getMessage());
                ExceptionUtils.error(ErrorCode.Request_ERROR, "请求失败");
            }


        }, taskExecutor);


//        System.out.println(config.getCharset());
        // 我的学习阶段是{高三},生成{10}道{数学}的{计算题}的题目
//        String prompt = "我的学习阶段是:" + stage + ",请生成" + count_direction +
//                "道" + direction + "【" + questions + "】" + "的题目,请一定要用 &&== 来分割每一道题目";
//        List<ChatMessage> msg = Collections.singletonList(new ChatMessage(prompt));
//
//        CompletableFuture.runAsync(() -> {
//            System.out.println("开始异步请求");
//            try {
//                // 调用 chatCompletions 方法
//                Map<String, Object> ret = serviceRequests.chatCompletions(ChatId, true, null, msg);
//                // 解析返回值
//                String lastValue = parseResponse(ret);
//
//                String[] split = lastValue.split("&&==");
//                if (split == null) {
//                    ExceptionUtils.error(ErrorCode.Request_ERROR, "问题分割符 &&== 出现问题");
//                }
////        测试
////        System.out.println("========================================");
////        for (String s : split) {
////            System.out.println(s);
////        }
////        System.out.println("========================================");
//
//                // 使用批量插入
//                // 创建一个固定大小的线程池来控制并发数
//                ExecutorService executor = Executors.newFixedThreadPool(10);
//                // 使用线程安全的集合存储结果
//                List<Question> questionList = Collections.synchronizedList(new ArrayList<>());
//
//                // 将每个元素的处理包装成异步任务
//                List<CompletableFuture<Void>> futures = Arrays.stream(split)
//                        .map(question_ -> CompletableFuture.runAsync(() -> {
//                            String content = Optional.ofNullable(question_)
//                                    .map(String::trim)
//                                    .orElse("");
//                            if (!content.isEmpty()) {
//                                // 执行网络请求（注意：此处会阻塞线程直至响应返回）
//                                String answer = genQuestionAnswer(content);
//                                Question question = new Question();
//                                question.setTags("[待审核]");
//                                question.setTitle(stage + direction); // 确保这些变量是final或线程安全的
//                                question.setUserid(userId);
//                                question.setContent(content);
//                                question.setAnswer(answer);
//                                questionList.add(question); // 线程安全操作
//                            }
//                        }, executor))
//                        .collect(Collectors.toList());
//
//                // 等待所有异步任务完成
//                CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
//                executor.shutdown(); // 关闭线程池释放资源
//
//                try {
//                    // 使用事务管理批量插入
//                    boolean saveResult = this.saveBatch(questionList); // 假设saveBatch是批量插入方法
//                    if (!saveResult) {
//                        ExceptionUtils.error(ErrorCode.SQL_ERROR, "[AI生成问题]插入数据失败");
//                    }
//                } catch (Exception e) {
//                    ExceptionUtils.error(ErrorCode.SQL_ERROR, "插入数据失败[可能是权限问题 ]");
//                }
//
//            } catch (Exception e) {
//                ExceptionUtils.error(ErrorCode.Request_ERROR, "请求失败");
//            }
//            System.out.println("异步请求结束");
////            ResultUtils.success("请求已经发送，等到处理完成");
//        });


//        // 调用 chatCompletions 方法
//        Map<String, Object> ret = serviceRequests.chatCompletions(ChatId, true, null, msg);
//
//
//        // 解析返回值
//        String lastValue = parseResponse(ret);
//
//
//        String[] split = lastValue.split("&&==");
//
//        if (split == null) {
//            ExceptionUtils.error(ErrorCode.Request_ERROR, "问题分割符 &&== 出现问题");
//        }
////        测试
////        System.out.println("========================================");
////        for (String s : split) {
////            System.out.println(s);
////        }
////        System.out.println("========================================");
//
//        // 使用批量插入
//        // 创建一个固定大小的线程池来控制并发数
//        ExecutorService executor = Executors.newFixedThreadPool(10);
//        // 使用线程安全的集合存储结果
//        List<Question> questionList = Collections.synchronizedList(new ArrayList<>());
//
//        // 将每个元素的处理包装成异步任务
//        List<CompletableFuture<Void>> futures = Arrays.stream(split)
//                .map(question_ -> CompletableFuture.runAsync(() -> {
//                    String content = Optional.ofNullable(question_)
//                            .map(String::trim)
//                            .orElse("");
//                    if (!content.isEmpty()) {
//                        // 执行网络请求（注意：此处会阻塞线程直至响应返回）
//                        String answer = genQuestionAnswer(content);
//                        Question question = new Question();
//                        question.setTags("[待审核]");
//                        question.setTitle(stage + direction); // 确保这些变量是final或线程安全的
//                        question.setUserid(userId);
//                        question.setContent(content);
//                        question.setAnswer(answer);
//                        questionList.add(question); // 线程安全操作
//                    }
//                }, executor))
//                .collect(Collectors.toList());
//
//        // 等待所有异步任务完成
//        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
//        executor.shutdown(); // 关闭线程池释放资源
//
//
//
//        try {
//            // 使用事务管理批量插入
//            boolean saveResult = this.saveBatch(questionList); // 假设saveBatch是批量插入方法
//            if (!saveResult) {
//                ExceptionUtils.error(ErrorCode.SQL_ERROR, "[AI生成问题]插入数据失败");
//            }
//        } catch (Exception e) {
//            ExceptionUtils.error(ErrorCode.SQL_ERROR, "插入数据失败[可能是权限问题 ]");
//        }

    }

    /**
     * 获取全部问题
     *
     * @param userId 用户ID
     * @return List<Question> 问题列表
     */
    public List<Question> getAllQuestion(int userId) {
        QueryWrapper<Question> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", userId);

        List<Question> questionList = questionMapper.selectList(queryWrapper);

        if (questionList == null || questionList.isEmpty()) {
            ExceptionUtils.error(ErrorCode.SQL_ERROR, "数据库里没有该用户的数据");
        }

        return geySafetyQuestion(questionList);
    }


    /**
     * 生成题解
     *
     * @param userId     用户ID
     * @param questionId 问题ID
     * @return boolean
     */
    @Override
    public String genQuestionAnswer(int userId, long questionId) {
        if (StringUtils.isAnyBlank(String.valueOf(userId), String.valueOf(questionId))) {
            ExceptionUtils.error(ErrorCode.PARAM_NOT_NULL, "用户ID || 问题ID 为空");
        }
        QueryWrapper<Question> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId", userId);
        queryWrapper.eq("id", questionId);
        List<Question> questionList = questionMapper.selectList(queryWrapper);
        if (questionList == null || questionList.isEmpty()) {
            ExceptionUtils.error(ErrorCode.SQL_ERROR, "用户为：" + userId + ",问题ID为：" + questionId + " 的问题不存在");
        }
        Question question = questionList.get(0);
        String content = question.getContent();

        // 配置请求参数
        Config config = new Config(
                "fastgpt-o6atl8iFwMyaxodwUBt17s0fGGX0nXqqH6jf6DmQrwonA43RUs97",
                "fastgpt-Y8oRqaoMpci2IntfVJPG4kw7k7efhZ3t1D8Dr83iY6m0A8BFYDAp"
        );

        // 进行AI网络请求
        ServiceRequests serviceRequests = new ServiceRequests(config);
        // 我的学习阶段是{高三},生成{10}道{数学}的{计算题}的题目
        List<ChatMessage> msg = Collections.singletonList(new ChatMessage(content));
        // 调用 chatCompletions 方法

        Map<String, Object> ret = serviceRequests.chatCompletions(String.valueOf(System.currentTimeMillis()), true, null, msg);

        return parseResponse(ret);
    }

    /**
     * 生成题解
     *
     * @param content 问题
     * @return boolean
     */
    @Override
    public String genQuestionAnswer(String content) {
        if (StringUtils.isAnyBlank(content)) {
            ExceptionUtils.error(ErrorCode.PARAM_NOT_NULL, "问题 为空");
        }
        // 配置请求参数
        Config config = new Config(
                KeyUtils.JtKey(AiKey.JtKey),
                KeyUtils.JtChatKey(AiKey.JtKey)
        );

        // 进行AI网络请求
        ServiceRequests serviceRequests = new ServiceRequests(config);
        // 我的学习阶段是{高三},生成{10}道{数学}的{计算题}的题目
        List<ChatMessage> msg = Collections.singletonList(new ChatMessage(content));
        // 调用 chatCompletions 方法

        Map<String, Object> ret = serviceRequests.chatCompletions(String.valueOf(System.currentTimeMillis()), true, null, msg);

        return parseResponse(ret);
    }


    /**
     * 问题脱敏
     *
     * @param questionList 原始问题列表
     * @return List<Question>  脱敏后的问题列表
     */
    public List<Question> geySafetyQuestion(List<Question> questionList) {
        List<Question> safetyQuestionList = new ArrayList<Question>();
        questionList.forEach(question -> {
            Question safetyQuestion = new Question();
            safetyQuestion.setId(question.getId());
            safetyQuestion.setTitle(question.getTitle());
            safetyQuestion.setContent(question.getContent());
            safetyQuestion.setTags(question.getTags());
            safetyQuestion.setUserid(question.getUserid());
            safetyQuestion.setCreatetime(question.getCreatetime());
            safetyQuestion.setEdittime(question.getEdittime());
            safetyQuestion.setAnswer(question.getAnswer());
            safetyQuestion.setUpdatetime(question.getUpdatetime());
            safetyQuestionList.add(safetyQuestion);
        });
        return safetyQuestionList;
    }


    /**
     * 解析AI返回的问题
     *
     * @param ret AI返回的内容
     * @return String 解析后的内容
     */
    public String parseResponse(Map<String, Object> ret) {
        if (ret == null) {
            ExceptionUtils.error(ErrorCode.Request_ERROR, "AI生成问题失败【可能是上下文到上限了？更换CharId】？【模型正在加载】");
        }

        List<Map<String, Object>> responseData = (List<Map<String, Object>>) ret.get("responseData");

        if (responseData == null || responseData.isEmpty()) {
            ExceptionUtils.error(ErrorCode.Request_ERROR, "responseData为空");
        }

        // 获取responseData中的第一个对象
        Map<String, Object> firstResponseData = responseData.get(0);

        // 获取historyPreview
        List<Map<String, String>> historyPreview = (List<Map<String, String>>) firstResponseData.get("historyPreview");

        // 检查historyPreview是否为空
        if (historyPreview == null || historyPreview.isEmpty()) {
            ExceptionUtils.error(ErrorCode.Request_ERROR, "historyPreview为空");
        }

        // 获取historyPreview的最后一个对象
        Map<String, String> lastHistoryPreview = historyPreview.get(historyPreview.size() - 1);

        // 获取最后一个对象的"value"字段
        return lastHistoryPreview.get("value");
    }


    /**
     * 批量插入问题
     *
     * @param stage     年级
     * @param direction 题目数量
     * @param direction 什么类型的题
     * @return List<Question>
     */

    private List<Question> generateQuestions(String[] split, String stage, String direction, int userId) {
        return Arrays.stream(split)
                .map(question_ -> createQuestion(question_, stage, direction, userId))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }


    /**
     * 返回问题对象
     *
     * @param content   问题
     * @param stage     年级
     * @param direction 学科
     * @param userId    用户ID
     * @return Question
     */
    private Question createQuestion(String content, String stage, String direction, int userId) {
        String answer = genQuestionAnswer(content);
        Question question = new Question();
        question.setTags(defaultTag);
        question.setTitle(stage + direction);
        question.setUserid(userId);
        question.setContent(content);
        question.setAnswer(answer);
        return question;
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void saveQuestionsAsync(List<Question> questionList) {
        boolean saveResult = this.saveBatch(questionList);
        if (!saveResult) {
            ExceptionUtils.error(ErrorCode.SQL_ERROR, "[AI生成问题]插入数据失败");
        }
    }
}




